package Modules::JunctionFilter;
use Data::Dumper;
use strict;

use Carp;
sub new {
  my ($class,$util) = @_;
  my $self = {
               'util' => $util,
             };
  bless $self,$class;
  return $self;
}

sub apply_filters {
  my $self           = shift;
  my $junctions      = shift;
  my $util           = $self->{'util'};
  my $intron_length  = $util->{'IL'    };
  my $coverage       = $util->{'COV'   };
  my $indels         = $util->{'INDELS'};
  my $min_flank      = $util->{'MIN_JUNC_FLANK'};
  my $path           = $util->{'DATA_PATH'};
  my $file           = $util->{'SAM_FILE' };
  
  print "intron_length: $intron_length\tcoverage: $coverage\tindels: $indels\tmin_flank: $min_flank\n";


  # Filter initialization
  my $no_junc             = 0;
  my $introns_too_short   = 0;
  my $not_enough_support  = 0;
  my $too_many_mismatches = 0;
  my $too_short_flank     = 0;
  
  
  open (my $fho ,'>'.$path.$file.'.junc') or die $!;
  open (my $fho1,'>'.$path.$file.'.pass.gff' ) or die $!;
  open (my $fho2,'>'.$path.$file.'.fail.gff' ) or die $!;
  
  print $fho "Reference\tStart\tEnd\tLength\tSupport\tNo_mismatches\tPASS/FAIL\n";
  
  foreach my $junc_name (sort {$a cmp $b} keys %{$junctions}) {

    my $filter             =  'N';
    my $reference          =  $junctions->{$junc_name}{'chr'          };
    my $junc_start         =  $junctions->{$junc_name}{'junc_start'   };
    my $junc_end           =  $junctions->{$junc_name}{'junc_end'     };
    my $junction_length    =  $junc_end - $junc_start;
    my $support            =  $junctions->{$junc_name}{'support'      };
    my $no_mismatches      =  $junctions->{$junc_name}{'no_mismatches'};   
    my $left_flank_size    =  $junctions->{$junc_name}{'junc_start'   }     - $junctions->{$junc_name}{'left_flank'}[0];
    my $right_flank_size   =  $junctions->{$junc_name}{'right_flank'  }[-1] - $junctions->{$junc_name}{'junc_end'};
    my $unique_map_support =  $junctions->{$junc_name}{'unique_map_support'} || 0;
    
    if ( $junction_length < $intron_length ) { 
      $introns_too_short++  ; 
      $filter = 'Y';
    }
    if ( $support         < $coverage      ) { 
      $not_enough_support++ ; 
      $filter = 'Y';
    }
    #if ( $indels          < $no_mismatches ) { 
    #  $too_many_mismatches++; 
    #  $filter = 'Y';
    #}
    if ( $min_flank > $left_flank_size ) {
      $too_short_flank++;
      $filter = 'Y';
    }

#    print "$junc_name\tunique_map_support: ".$unique_map_support."\t";
#    print "support: $support\n";
       
    #print "$left_flank_size\t$right_flank_size\n" if $left_flank_size < 5;
    #warn $min_flank;
    my $pass_or_fail    = ($filter eq 'Y')? 'FAIL' : 'PASS';
    print $fho "$reference\t$junc_start\t$junc_end\t$junction_length\t$support\t$no_mismatches\t$pass_or_fail\n";
    
    if ($filter eq 'Y') {
      $self->write_gff($junctions->{$junc_name},$junc_name,$fho2);
      next;
    }
    
    $self->write_gff($junctions->{$junc_name},$junc_name,$fho1);    
    $no_junc++;
    
  }
  close $fho;
  close $fho1;
  
print Dumper $junctions->{'456705_456776_Mp1087439_TGAC_V1_scaffold_344'};
my $left_flank = scalar @{$junctions->{'456705_456776_Mp1087439_TGAC_V1_scaffold_344'}{'left_flank'}} ;
my $read_names = scalar @{$junctions->{'456705_456776_Mp1087439_TGAC_V1_scaffold_344'}{'read_names'}} ;
print "left flank: $left_flank\n";
print "read names: $read_names\n";
  
  print "\nNo. junctions AFTER filtering:        " . $no_junc;
  print "\nNo. introns too short:                " . $introns_too_short;
  print "\nNo. introns w/o enough support:       " . $not_enough_support;
  print "\nNo. junctions w/ too many mismatches: " . $too_many_mismatches;
  print "\nNo. junctions w/ flanks too short:    " . $too_short_flank."\n";
  return;
}

sub write_gff {
  my ($self,$junction,$junc_name,$fho1) = @_;
  #match
  print $fho1 $junction->{'chr'         }    . "\tSAM\tmatch\t"
             .$junction->{'left_flank'  }[0 ]. "\t"
             .$junction->{'right_flank' }[-1]. "\t"
             .$junction->{'support'     }    . "\t"
             .$junction->{'query_strand'}    . "\t.\t"
             ."ID=".$junc_name.";Name=".$junc_name.";Note="
             .$junction->{'support'    }     . "\n";
  # left match_part          
  print $fho1 $junction->{'chr'         }    . "\tSAM\tmatch_part\t"
             .$junction->{'left_flank'  }[0 ]. "\t"
             .$junction->{'junc_start'  }    . "\t"
             .$junction->{'support'     }    . "\t"
             .$junction->{'query_strand'}    . "\t.\t"
             ."Parent=".$junc_name           . "\n";
  # right match_part  
  print $fho1 $junction->{'chr'         }    . "\tSAM\tmatch_part\t"
             .$junction->{'right_flank' }[-1]. "\t"
             .$junction->{'junc_end'    }    . "\t"
             .$junction->{'support'     }    . "\t"
             .$junction->{'query_strand'}    . "\t.\t"
             ."Parent=".$junc_name           . "\n";         
  return;
}

1;